home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / bbsutil / bsrc_250.zip / SPAWN.ASM < prev    next >
Assembly Source File  |  1991-08-04  |  47KB  |  2,087 lines

  1. ;
  2. ;    --- Version 3.0 91-05-27 17:56 ---
  3. ;
  4. ;    SPAWN.ASM - Main function for memory swapping spawn call.
  5. ;
  6. ;    Public Domain Software written by
  7. ;        Thomas Wagner
  8. ;        Ferrari electronic GmbH
  9. ;        Beusselstrasse 27
  10. ;        D-1000 Berlin 21
  11. ;        Germany
  12. ;
  13. ;
  14. ; Assemble with
  15. ;
  16. ; tasm  /DPASCAL spawn,spawnp          - Turbo Pascal (Tasm only), near
  17. ; tasm  /DPASCAL /DFARCALL spawn,spawnp    - Turbo Pascal (Tasm only), far
  18. ; ?asm  spawn;                  - C, default model (small)
  19. ; ?asm  /DMODL=large spawn          - C, large model
  20. ;
  21. ;    NOTE:    For C, change the 'model' directive below according to your
  22. ;        memory model, or define MODL=xxx on the command line.
  23. ;
  24. ;        For Turbo C Huge model, you must give /DTC_HUGE on the
  25. ;        command line, or define it here.
  26. ;
  27. ;
  28. ; Main function:
  29. ;
  30. ;   PASCAL:
  31. ;       function do_spawn (swapping: integer; 
  32. ;                  execfname: string;
  33. ;               cmdtail: string; 
  34. ;                  envlen: word; 
  35. ;               var envp)
  36. ;
  37. ;   C:
  38. ;       int do_spawn (int swapping,
  39. ;              char *execfname, 
  40. ;              char *cmdtail,
  41. ;              unsigned envlen, 
  42. ;              char *envp)
  43. ;
  44. ;   Parameters:
  45. ;
  46. ;    swapping - swap/spawn/exec function:
  47. ;            < 0: Exec, don't swap
  48. ;                0: Spawn, don't swap
  49. ;            > 0: Spawn, swap
  50. ;                 in this case, prep_swap must have 
  51. ;                 been called beforehand (see below).
  52. ;
  53. ;    cmdtail - command tail for EXEC.
  54. ;
  55. ;    execfname - name and path of file to execute.
  56. ;
  57. ;    envlen - length of environment copy (may be 0).
  58. ;
  59. ;    envp -  pointer to environment block (must be aligned on
  60. ;        paragraph boundary). Unused if envlen is 0.
  61. ;
  62. ;    'cmdtail' and 'execfname' must be zero terminated, even when
  63. ;    calling from Pascal. For Pascal, the length byte of the string
  64. ;    is ignored.
  65. ;
  66. ;   Returns:
  67. ;    0000..00ff:    Returncode of EXECed program
  68. ;    03xx:        DOS-Error xx calling EXEC
  69. ;    0500:        Swapping requested, but prep_swap has not 
  70. ;            been called or returned an error
  71. ;    0501:        MCBs don't match expected setup
  72. ;    0502:        Error while swapping out
  73. ;
  74. ;
  75. ; For swapping, the swap method must be prepared before calling do_spawn.
  76. ;
  77. ;   PASCAL:
  78. ;    function prep_swap (method: word; swapfname: string): integer;
  79. ;   C:
  80. ;    int prep_swap (unsigned method, char *swapfname)
  81. ;
  82. ;   Parameters:
  83. ;
  84. ;    method    - bit-map of allowed swap devices:
  85. ;            01 - Allow EMS
  86. ;            02 - Allow XMS
  87. ;            04 - Allow File swap
  88. ;            10 - Try XMS first, then EMS
  89. ;            40 - Create file as "hidden"
  90. ;            80 - Use "create temp" call for file swap
  91. ;               100 - Don't preallocate file
  92. ;               200 - Check for Network, don't preallocate if net
  93. ;              4000 - Environment block will not be swapped
  94. ;
  95. ;    swapfname - swap file name (may be undefined if the
  96. ;            "method" parameters disallows file swap).
  97. ;            The string must be zero terminated, even
  98. ;            when calling from Pascal. For Pascal, the 
  99. ;            length byte of the string is ignored.
  100. ;
  101. ;   Returns:
  102. ;
  103. ;       A positive integer on success:
  104. ;        1 - EMS swap initialized
  105. ;        2 - XMS swap initialized
  106. ;        4 - File swap initialized
  107. ;    A negative integer on failure:
  108. ;        -1 - Couldn't allocate swap space
  109. ;        -2 - The spawn module is located too low in memory
  110. ;
  111. ;
  112.     IFDEF    PASCAL
  113.     .model    tpascal
  114. ;
  115.     extrn    prefixseg: word
  116. ;
  117. ptrsize    =    1
  118.     ELSE
  119.     IFNDEF    MODL
  120.     .model    small,c
  121.     ELSE
  122. %    .model    MODL,c
  123.     ENDIF
  124. ;
  125. ptrsize    =    @DataSize
  126. ;
  127.     extrn    _psp: word
  128.     ENDIF
  129. ;
  130.     public    do_spawn
  131.     public    prep_swap
  132. ;
  133. stacklen    =    256        ; local stack
  134. ;
  135. ;    "ems_size" is the EMS block size: 16k.
  136. ;
  137. ems_size    =    16 * 1024    ; EMS block size
  138. ems_parasize    =    ems_size / 16    ; same in paragraphs
  139. ems_shift    =    10        ; shift factor for paragraphs
  140. ems_paramask    =    ems_parasize-1    ; block mask
  141. ;
  142. ;    "xms_size" is the unit of measurement for XMS: 1k
  143. ;
  144. xms_size    =    1024        ; XMS block size
  145. xms_parasize    =    xms_size / 16    ; same in paragraphs
  146. xms_shift    =    6        ; shift factor for paragraphs
  147. xms_paramask    =    xms_parasize-1    ; block mask
  148. ;
  149. ;    Method flags
  150. ;
  151. USE_EMS        =    01h
  152. USE_XMS        =    02h
  153. USE_FILE    =    04h
  154. XMS_FIRST    =    10h
  155. HIDE_FILE    =    40h
  156. CREAT_TEMP    =    80h
  157. NO_PREALLOC    =    100h
  158. CHECK_NET    =    200h
  159. DONT_SWAP_ENV    =    4000h
  160. ;
  161. ;    Return codes
  162. ;
  163. RC_TOOLOW    =    0102h
  164. RC_BADPREP    =    0500h
  165. RC_MCBERROR    =    0501h
  166. RC_SWAPERROR    =    0502h
  167. ;
  168. EMM_INT        =    67h
  169. ;
  170. ;    The EXEC function parameter block
  171. ;
  172. exec_block    struc
  173. envseg    dw    ?        ; environment segment
  174. ppar    dw    ?        ; program parameter string offset
  175. pparseg    dw    ?        ; program parameter string segment
  176. fcb1    dw    ?        ; FCB offset
  177. fcb1seg    dw    ?        ; FCB segment
  178. fcb2    dw    ?        ; FCB offset
  179. fcb2seg    dw    ?        ; FCB segment
  180. exec_block    ends
  181. ;
  182. ;    Structure of an XMS move control block
  183. ;
  184. xms_control    struc
  185. lenlo        dw    ?    ; length to move (doubleword)
  186. lenhi        dw    ?
  187. srchnd        dw    ?    ; source handle (0 for standard memory)
  188. srclo        dw    ?    ; source address (doubleword or seg:off)
  189. srchi        dw    ?
  190. desthnd        dw    ?    ; destination handle (0 for standard memory)
  191. destlo        dw    ?    ; destination address (doubleword or seg:off)
  192. desthi        dw    ?
  193. xms_control    ends
  194. ;
  195. ;    The structure of the start of an MCB (memory control block)
  196. ;
  197. mcb        struc
  198. id        db    ?
  199. owner        dw    ?
  200. paras        dw    ?
  201. mcb        ends
  202. ;
  203. ;    The structure of an internal MCB descriptor.
  204. ;    CAUTION: This structure is assumed to be no larger than 16 bytes
  205. ;    in several places in the code, and to be exactly 16 bytes when
  206. ;    swapping in from file. Be careful when changing this structure.
  207. ;
  208. mcbdesc        struc
  209. addr        dw    ?    ; paragraph address of the MCB
  210. msize        dw    ?    ; size in paragraphs (excluding header)
  211. swoffset    dw    ?    ; swap offset (0 in all blocks except first)
  212. swsize        dw    ?    ; swap size (= msize + 1 except in first)
  213. num_follow    dw    ?    ; number of following MCBs
  214.         dw    3 dup(?) ; pad to paragraph (16 bytes)
  215. mcbdesc        ends
  216. ;
  217. ;    The variable block set up by prep_swap
  218. ;
  219. prep_block    struc
  220. xmm        dd    ?        ; XMM entry address
  221. first_mcb    dw    ?        ; Segment of first MCB
  222. psp_mcb        dw    ?        ; Segment of MCB of our PSP
  223. env_mcb        dw    ?        ; MCB of Environment segment
  224. noswap_mcb    dw    ?        ; MCB that may not be swapped
  225. ems_pageframe    dw    ?        ; EMS page frame address
  226. handle        dw    ?        ; EMS/XMS/File handle
  227. total_mcbs    dw    ?        ; Total number of MCBs
  228. swapmethod    db    ?        ; Method for swapping
  229. swapfilename    db    81 dup(?)    ; Swap file name if swapping to file
  230. prep_block    ends
  231. ;
  232. ;----------------------------------------------------------------------
  233. ;
  234. ;    Since we'll be moving code and data around in memory,
  235. ;    we can't address locations in the resident block with
  236. ;    normal address expressions. MASM does not support
  237. ;    defining variables with a fixed offset, so we have to resort
  238. ;    to a kludge, and define the shrunk-down code as a structure.
  239. ;    It would also be possible to use an absolute segment for the
  240. ;    definition, but this is not supported by the Turbo Pascal linker.
  241. ;
  242. ;    All references to low-core variables from low-core itself 
  243. ;    are made through DS, so we define a text macro "lmem" that 
  244. ;    expands to "ds:". When setting up low core from the normal
  245. ;    code, ES is used to address low memory, so this can't be used.
  246. ;
  247. lmem    equ    <ds:>
  248. ;
  249. ;    The memory structure for the shrunk-down code, excluding the
  250. ;    code itself. The code follows this block.
  251. ;
  252. parseg        struc
  253.         db    2ch dup(?)
  254. psp_envptr    dw    ?
  255.         db    5ch-2eh dup(?)    ; start after PSP
  256. ;
  257. save_ss        dw    ?        ; 5C - saved global ss
  258. save_sp        dw    ?        ; 5E - saved global sp
  259. xfcb1        db    16 dup(?)    ; 60..6F - default FCB
  260. xfcb2        db    16 dup(?)    ; 70..7F - default FCB
  261. zero        dw    ?        ; 80 Zero command tail length (dummy)
  262. ;
  263. expar        db    TYPE exec_block dup (?) ; exec-parameter-block
  264. spx        dw    ?        ; saved local sp
  265. div0_off    dw    ?        ; divide by zero vector save
  266. div0_seg    dw    ?
  267. filename    db    82 dup(?)    ; exec filename
  268. progpars    db    128 dup(?)    ; command tail
  269.         db    stacklen dup(?)    ; local stack space
  270. mystack        db    ?
  271. lprep        db    TYPE prep_block dup(?)    ; the swapping variables
  272. lcurrdesc    db    TYPE mcbdesc dup(?)    ; the current MCB descriptor
  273. lxmsctl        db    TYPE xms_control dup(?)
  274. eretcode    dw    ?        ; EXEC return code
  275. retflags    dw    ?        ; EXEC return flags
  276. cgetmcb        dw    ?        ; address of get_mcb
  277. ;
  278. parseg    ends
  279. ;
  280. param_len    =    ((TYPE parseg + 1) / 2) * 2    ; make even
  281. codebeg        =    param_len
  282. ;
  283.     .code
  284. ;
  285. ;------------------------------------------------------------------------
  286. ;
  287. lowcode_begin:
  288. ;
  289. ;       The following parts of the program code will be moved to
  290. ;    low core and executed there, so there